package com.sherlocky.util;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class WebUtil {
	private static Log logger = LogFactory.getLog(WebUtil.class);
	/*
     * This pattern creates tokens, where each line starts with the tag.
     * For example, "One, <b>Two</b>, Three" produces the following:
     *     One,
     *     <b>Two
     *     </b>, Three
     */
    static Pattern tagPattern = Pattern.compile("(<.+?>)?([^<>]*)");

    /*
     * Checks for an empty tag, for example img, br, etc.
     */
    static Pattern emptyTagPattern = Pattern.compile("^<\\s*(img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param).*>$");

    /*
     * Modified the pattern to also include H1-H6 tags
     * Checks for closing tags, allowing leading and ending space inside the brackets
     */
    static Pattern closingTagPattern = Pattern.compile("^<\\s*/\\s*([a-zA-Z]+[1-6]?)\\s*>$");

    /*
     * Modified the pattern to also include H1-H6 tags
     * Checks for opening tags, allowing leading and ending space inside the brackets
     */
    static Pattern openingTagPattern = Pattern.compile("^<\\s*([a-zA-Z]+[1-6]?).*?>$");

    /*
     * Find &nbsp; &gt; ...
     */
    static Pattern entityPattern = Pattern.compile("(&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};)");
    
	public static String getClientIP(HttpServletRequest request) {
		if (request == null) {
			return "";
		}
		String ip = request.getHeader("x-forwarded-for");
		if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("http_client_ip");
		}
		if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("HTTP_X_FORWARDED_FOR");
		}
		if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		
		String[] ips = new String[0];
		if (StringUtils.isNotEmpty(ip)) {
			ips = ip.split(",");
		}
		 // 如果是多级代理，那么取第一个ip为客户ip
		for (int i = 0; i < ips.length; i++) {
			if (!"unknown".equalsIgnoreCase(ips[i])) {
				ip = ips[i];
				break;
			}
		}
		return ip;
	}
	
	public static String getClientExplorer(HttpServletRequest request) {

		String explorer = "未知";   
		String info = request.getHeader("user-agent");
		if(StringUtils.isEmpty(info)) {
			return null;
		}
		Pattern pattern = Pattern.compile("");   
		Matcher matcher;   
		if(info.indexOf("MSIE") != -1){   
			explorer = "IE"; //微软IE   
			pattern = Pattern.compile(explorer + "\\s([0-20.]+)");   
		}else if(info.indexOf("Firefox") != -1){   
			explorer = "Firefox"; // 火狐
			pattern = Pattern.compile(explorer + "\\/([0-9.]+)");   
		}else if(info.indexOf("Chrome") != -1){   
			explorer = "Chrome"; //Google   
			pattern = Pattern.compile(explorer + "\\/([0-9.]+)");   
		}else if(info.indexOf("Opera") != -1){   
			explorer = "Opera"; //Opera   
			pattern = Pattern.compile("Version\\/([0-9.]+)");   
		}else if(info.indexOf("Safari") != -1){   
			explorer = "Safari"; //Safari   
			pattern = Pattern.compile("Version\\/([0-9.]+)");   
		}else if(StringUtils.containsIgnoreCase(info, "iphone")) {
			explorer = "iphone";
			pattern = Pattern.compile("iPhone\\s+OS\\s+([0-9.]+)");
		}else if(StringUtils.containsIgnoreCase(info, "android")) {
			explorer = "android";
			pattern = Pattern.compile("android\\s*([0-9.]+)", Pattern.CASE_INSENSITIVE);
		}
		matcher = pattern.matcher(info);   

		try {
			if (matcher.find( 1 )) {
				explorer += " " + matcher.group(1);
			}
		} catch (Exception e) {
			logger.error(e.getMessage());
		}

		return explorer;  
	}
	
	public static boolean isMobileExplorer(HttpServletRequest request) {
		String info = request.getHeader("user-agent");
		return StringUtils.containsIgnoreCase(info, "mobile");
	}
	
	/**
	 * 截取html代码为某个长度
	 * @param text
	 * @param length
	 * @param suffix 截取后文本显示的附加文本
	 * @return
	 */
	public static String truncateHTML(String text, int length, String suffix) {
	    // if the plain text is shorter than the maximum length, return the whole text
	    if (text.replaceAll("<.*?>", "").length() <= length) {
	        return text;
	    }
	    String result = "";
	    boolean trimmed = false;
	    if (suffix == null) {
	        suffix = "...";
	    }

	    // splits all html-tags to scanable lines
	    Matcher tagMatcher =  tagPattern.matcher(text);
	    int numTags = tagMatcher.groupCount();

	    int totalLength = suffix.length();
	    List<String> openTags = new ArrayList<String>();

	    boolean proposingChop = false;
	    while (tagMatcher.find()) {
	        String tagText = tagMatcher.group(1);
	        String plainText = tagMatcher.group(2);

	        if (proposingChop &&
	                tagText != null && tagText.length() != 0 &&
	                plainText != null && plainText.length() != 0) {
	            trimmed = true;
	            break;
	        }

	        // if there is any html-tag in this line, handle it and add it (uncounted) to the output
	        if (tagText != null && tagText.length() > 0) {
	            boolean foundMatch = false;

	            // if it's an "empty element" with or without xhtml-conform closing slash
	            Matcher matcher = emptyTagPattern.matcher(tagText);
	            if (matcher.find()) {
	                foundMatch = true;
	                // do nothing
	            }

	            // closing tag?
	            if (!foundMatch) {
	                matcher = closingTagPattern.matcher(tagText);
	                if (matcher.find()) {
	                    foundMatch = true;
	                    // delete tag from openTags list
	                    String tagName = matcher.group(1);
	                    openTags.remove(tagName.toLowerCase());
	                }
	            }

	            // opening tag?
	            if (!foundMatch) {
	                matcher = openingTagPattern.matcher(tagText);
	                if (matcher.find()) {
	                    // add tag to the beginning of openTags list
	                    String tagName = matcher.group(1);
	                    openTags.add(0, tagName.toLowerCase());
	                }
	            }

	            // add html-tag to result
	            result += tagText;
	        }

	        // calculate the length of the plain text part of the line; handle entities (e.g. &nbsp;) as one character
	        int contentLength = plainText.replaceAll("&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};", " ").length();
	        if (totalLength + contentLength > length) {
	            // the number of characters which are left
	            int numCharsRemaining = length - totalLength;
	            int entitiesLength = 0;
	            Matcher entityMatcher = entityPattern.matcher(plainText);
	            while (entityMatcher.find()) {
	                String entity = entityMatcher.group(1);
	                if (numCharsRemaining > 0) {
	                    numCharsRemaining--;
	                    entitiesLength += entity.length();
	                } else {
	                    // no more characters left
	                    break;
	                }
	            }

	            // keep us from chopping words in half
	            int proposedChopPosition = numCharsRemaining + entitiesLength;
	            int endOfWordPosition = plainText.indexOf(" ", proposedChopPosition-1);
	            if (endOfWordPosition == -1) {
	                endOfWordPosition = plainText.length();
	            }
	            int endOfWordOffset = endOfWordPosition - proposedChopPosition;
	            if (endOfWordOffset > 6) { // chop the word if it's extra long
	                endOfWordOffset = 0;
	            }

	            proposedChopPosition = numCharsRemaining + entitiesLength + endOfWordOffset;
	            if (plainText.length() >= proposedChopPosition) {
	                result += plainText.substring(0, proposedChopPosition);
	                proposingChop = true;
	                if (proposedChopPosition < plainText.length()) {
	                    trimmed = true;
	                    break; // maximum length is reached, so get off the loop
	                }
	            } else {
	                result += plainText;
	            }
	        } else {
	            result += plainText;
	            totalLength += contentLength;
	        }
	        // if the maximum length is reached, get off the loop
	        if(totalLength >= length) {
	            trimmed = true;
	            break;
	        }
	    }

	    for (String openTag : openTags) {
	        result += "</" + openTag + ">";
	    }
	    if (trimmed) {
	        result += suffix;
	    }
	    return result;
	}
	
	/** 
     * html转化为text 
     * @param inputString 
     * @return 
     */ 
    public static String html2Text(String inputString) { 
          String htmlStr = inputString; // 含html标签的字符串 
          String textStr = ""; 
          java.util.regex.Matcher m_html; 
          Pattern closingTagPattern = Pattern.compile("<\\s*/\\s*([a-zA-Z]+[1-6]?)\\s*>");
          /*
           * Modified the pattern to also include H1-H6 tags
           * Checks for opening tags, allowing leading and ending space inside the brackets
           */
          Pattern openingTagPattern = Pattern.compile("<\\s*([a-zA-Z]+[1-6]?).*?>");
          /*
           * Find &nbsp; &gt; ...
           */
          Pattern entityPattern = Pattern.compile("(&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};)");
           m_html = openingTagPattern.matcher(htmlStr); 
           htmlStr = m_html.replaceAll(""); // 过滤html开始标签 
           
           m_html = closingTagPattern.matcher(htmlStr); 
           htmlStr = m_html.replaceAll(""); // 过滤html结束标签 
           
           m_html = entityPattern.matcher(htmlStr); 
           htmlStr = m_html.replaceAll(""); // 过滤html标签 

           textStr = htmlStr; 
          return textStr; 
        } 

	
	public static void main(String[] args) {
		String str = "com.lezhixing.campus/1.0.0 (unknown, iPhone OS 6.1.2, iPad, Scale/1.000000)";
		System.out.println(Pattern.compile("iPhone\\s+OS\\s+([0-9.]+)").matcher(str).find( 1 ));
	}
}
